package com.unitd.frame.springweb.plugins.velocity.directive;

import org.apache.velocity.context.InternalContextAdapter;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.directive.Directive;
import org.apache.velocity.runtime.parser.node.Node;
import org.apache.velocity.runtime.parser.node.SimpleNode;

import java.io.IOException;
import java.io.Writer;

/**
 * @desc 自定义一个Velocity的指令类, 用于一个子velocity页面在继承自父velocity页面的同时, 重写父页面的某个节点块
 * @filename OverrideDirective.java
 * @copyright www.unitd.com
 * @author Hudan
 * @version 1.0
 * @date 2017/4/2
 */
public class OverrideDirective extends Directive {

	public OverrideDirective() {
	}

	@Override
	public String getName() {
		return "override";
	}

	@Override
	public int getType() {
		return 1;
	}

	@Override
	public boolean render(InternalContextAdapter context, Writer writer, Node node) throws IOException, ResourceNotFoundException, ParseErrorException, MethodInvocationException {
		String name = DirectiveUtil.getRequiredArgument(context, node, 0, this.getName());
		OverrideNodeWrapper override = (OverrideNodeWrapper) context.get(DirectiveUtil.getOverrideVariableName(name));
		if (override == null) {
			Node current = node.jjtGetChild(1);
			context.put(DirectiveUtil.getOverrideVariableName(name), new OverrideNodeWrapper(current));
		} else {
			OverrideNodeWrapper current1 = new OverrideNodeWrapper(node.jjtGetChild(1));
			DirectiveUtil.setParentForTop(current1, override);
		}

		return true;
	}

	private boolean isOverrided(InternalContextAdapter context, String name) {
		return context.get(DirectiveUtil.getOverrideVariableName(name)) != null;
	}

	static class OverrideNodeWrapper extends SimpleNode {
		Node current;
		OverrideNodeWrapper parentNode;

		public OverrideNodeWrapper(Node node) {
			super(1);
			this.current = node;
		}

		@Override
		public boolean render(InternalContextAdapter context, Writer writer) throws IOException, MethodInvocationException, ParseErrorException, ResourceNotFoundException {
			OverrideNodeWrapper preNode = (OverrideNodeWrapper) context.get(DirectiveUtil.OVERRIDE_CURRENT_NODE);

			boolean var4;
			try {
				context.put(DirectiveUtil.OVERRIDE_CURRENT_NODE, this);
				var4 = this.current.render(context, writer);
			} finally {
				context.put(DirectiveUtil.OVERRIDE_CURRENT_NODE, preNode);
			}

			return var4;
		}
	}
}